#include <iostream>
#include <vector>
#include <cmath>
#include "../spline_functions.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

int main() {
    // 定义节点和系数
    std::cout << "-------Problem 3: Testing B-3-spline by the function 'y = sin(pi*x)'-------" << std::endl;
    std::vector<double> knots = {0, 0.3, 1, 1.6, 2};
    // std::vector<double> coefficients = {sin(pi()*0), sin(pi()*0), sin(pi()*0), sin(pi()*0), sin(pi()*0)};
    std::vector<double> coefficients;
    for (double knot : knots) {
        coefficients.push_back(sin(M_PI * knot));
    }

    // 创建周期边界条件三次样条对象
    PeriodicCubicSpline_B periodicSpline_B(3, knots, coefficients);
    // 创建自然三次样条对象
    NaturalSpline_B naturalSpline_B(3, knots, coefficients);
    // 创建完全三次样条对象
    ClampedCubicSpline_B clampedSpline_B(3, knots, coefficients, M_PI, M_PI);

    // 定义要评估的点
    std::vector<double> points = {1.0/6, 0.25, 1.0/3};

    // 评估样条函数在这些点的值
    std::cout << "---Part1. Testing PeriodicCubicSpline_B:" << std::endl;
    for (double x : points) {
        try {
            double value = periodicSpline_B.evaluate(x);
            std::cout << "B Periodic cubic spline value at x = " << x << " is " << value << std::endl;
        } catch (const std::exception& e) {
            std::cerr << "Error evaluating periodic cubic spline at x = " << x << ": " << e.what() << std::endl;
        }
    }

    std::cout << "---Part2. Testing NaturalSpline_p:" << std::endl;
    for (double x : points) {
        try {
            double value = naturalSpline_B.evaluate(x);
            std::cout << "B Natural cubic spline value at x = " << x << " is " << value << std::endl;
        } catch (const std::exception& e) {
            std::cerr << "Error evaluating natural cubic spline at x = " << x << ": " << e.what() << std::endl;
        }
    }

    std::cout << "---Part3. ClampedCubicSpline_p:" << std::endl;
    for (double x : points) {
        try {
            double value = clampedSpline_B.evaluate(x);
            std::cout << "B Clamped cubic spline value at x = " << x << " is " << value << std::endl;
        } catch (const std::exception& e) {
            std::cerr << "Error evaluating clamped cubic spline at x = " << x << ": " << e.what() << std::endl;
        }
    }

    return 0;
}